<?

/////////////////////////////////////////////////////////////////////////////////////////
// Clase para Manejar Bases por OBDC
/////////////////////////////////////////////////////////////////////////////////////////

/// class DatabaseODBC 
class DatabaseODBC {

	// Propiedades de la Conexion
	var $cDsn = "";
	var $cUser = "";
	var $cPassword = "";
	var $idCon = 0;

	// Propiedades para el manejo de resultsets
	var $idQuery = 0;
	var $cantCampos = 0;
	var $aDatos = array();

	function dbLower( $cString ) {
		return " lcase($cString) ";
	}
	
	function dbNumToStr( $cString ) {
		return " lcase($cString) ";
	}

	function dbDateToStr( $cString , $cFormato ) {
		return " FORMAT( $cString, $cFormato ) ";
	}

	function dbValue ( $cValor ) {
		$cValor = trim($cValor);
		
		if ( $cValor === "")  {
			$cValor = "null";
		} else {
	//		if ( $cValor && is_numeric ( $cValor)  == false ) {		
				if ( ! (strpos( $cValor, "'" )  === FALSE) ) {
					$cValor = str_replace( "'", "''", $cValor);
				}
				
				// Quita los '.00' de un NNN.00 (por BUG del freetds )			
				if ( substr($cValor, -3 ) === ".00" ) {
						$cValor = substr($cValor, 0, -3 );
				}
				$cValor = "'$cValor'";
			}
	//	}
		
		return $cValor;
	}
	
	function DatabaseODBC($cDsn, $cDatabase, $cUser = "", $cPassword = ""){		
		$this->cDsn = $cDsn;
		$this->cUser = $cUser;
		$this->cPassword = $cPassword;
		$this->idCon = 0;
		$this->eof = true;
	}

	function status() {
		return 'DNS: ' . $this->cDsn .' User: ' . $this->cUser . ' ' . ' ConId: ' . $this->idCon ;
	}
	
	function connect( $bPersistente = false) {		
		if ( $bPersistente ) {
			$this->idCon = odbc_pconnect( $this->cDsn, $this->cUser, $this->cPassword );
		} else {
			$this->idCon = odbc_connect( $this->cDsn, $this->cUser, $this->cPassword );			
		}

		// Hubo un Error !
		if ( $this->idCon == 0 ) {
			addMessage("Error al intentar conectarse" );
			return FALSE;
		}

		return $this->idCon;
	}

	function nextKey ( $cTabla, $cCampo, $cCondicion = "" ) {
		$nCodigo = 0;
		$cSql = "Select Max( ". $cCampo . ") From " . $cTabla;

		if ( $cCondicion != "" )
			$cSql .=  " Where " . $cCondicion;

		$nCodigo = $this->getData ( $cSql );

		return $nCodigo == NULL ? 1: ($nCodigo + 1);
	}

	function getData( $cSql ) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;
		
		$nQuery = 0;
		$cReturn = "";
		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$nQuery = odbc_exec ( $this->idCon, $cSql);

		if ( $nQuery == TRUE ) {

			if ( odbc_num_rows( $nQuery ) != 0 )
				$cReturn = odbc_result( $nQuery , 1);

			odbc_free_result ( $nQuery );

		} else {
			addMessage( "Error en el query: ($nQuery) $cSql" );
		}

		return $cReturn;

	}

	function getMatrix ( $cSql ) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;
		
		$nQuery = 0;
		$aReturn = array();
		$aRow = array();

		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$nQuery = odbc_exec ( $this->idCon, $cSql);

		if ( $nQuery == TRUE ) {
						
			while( odbc_fetch_into($nQuery, $aRow )) {
				$aReturn[] = $aRow;
			}
			odbc_free_result ( $nQuery );
		} 
		else 
		{
			addMessage( "Error en el query: $cSql");
		}

		return $aReturn;
	}

	function getKeyArray( $cSql ) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;
		
		$nQuery = 0;
		$aReturn = array();
		$aRow = array();

		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$nQuery = odbc_exec ( $this->idCon, $cSql);

		if ( $nQuery == TRUE ) {
			
			$aRow = odbc_fetch_row($nQuery );
			// Si es solo Codigo y Descripcion
			if ( count($aRow) == 2 ) {
				if ( $aRow ) {
					do {
						$aReturn[$aRow[0]] = $aRow[1];
						$aRow = odbc_fetch_row($nQuery );
					} while ( $aRow );
				}
			} else {
				// Si son Varios => Arma Array
				if ( $aRow ) {
					do {
						for ( $nRow = 0; $nRow < count($aRow) ; $nRow++ )
							$aReturn[$aRow[0]][] = $aRow[$nRow];

						$aRow = odbc_fetch_row($nQuery );
					} while ( $aRow );
				}
			}




			odbc_free_result ( $nQuery );
		} else {
			addMessage( "Error en el query: $cSql");
		}

		return $aReturn;
	}

	function getArray( $cSql ) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;
		
		$nQuery = 0;
		$aReturn = array();
		$aRow = array();	
		
		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
			return false;

		$nQuery = odbc_exec ( $this->idCon, $cSql);

		if ( $nQuery == TRUE ) {		
			while( odbc_fetch_into($nQuery, $aRow  )) {			
				// lo hace Asociativo
				for( $nIndex = 0 ; $nIndex < odbc_num_fields( $nQuery ); $nIndex ++ ) {					
					$aRow[odbc_field_name ($nQuery, $nIndex + 1)] =  $aRow[$nIndex];
				}
				
				if ( count($aRow)  == 2) {
					$aReturn = array_merge( (array)$aReturn, (array)$aRow[0] );
				} else{
					$aReturn = array_merge((array)$aReturn, (array)$aRow );
				}				
			}
			
			odbc_free_result ( $nQuery );
		} else {
			addMessage("Error en el query: $cSql");
		}

		return $aReturn;
	}

	function insert( $cTabla, $cCampo, $cValor ) {
		$nContador = 0;
		$bPrimero = true;

		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$this->cSql = "INSERT INTO " . $cTabla . " ( ";

		for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) {
			if ( $bPrimero )
				$bPrimero = false;
			else
				$this->cSql .= ", ";

			$this->cSql .= func_get_arg($nContador);

		}

		$this->cSql .= ") VALUES ( ";

		$bPrimero = true;
		for ( $nContador = 2; $nContador < func_num_args();  $nContador+=2  ) {
			$cValor = $this->dbValue( func_get_arg($nContador) );
			if ( $bPrimero )
				$bPrimero = false;
			else
				$this->cSql .= ", ";

			$this->cSql .= $cValor ;
		}

		$this->cSql .= ")";
		$bExito = ( odbc_exec ( $this->idCon, $this->cSql) == FALSE ) ? false:  true;

		if($bExito === false) {
			addMessage($this->cSql);
		}


		return $bExito;
	}


	function update ( $cTabla, $cCampo, $cValor, $Where, $cClave, $cValor ) {
		$nContador = 0;
		$bPrimero = true;
		$cSeparador = ", ";

		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$cSql = "UPDATE " . $cTabla . " SET ";

		for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) {
			if (!strcasecmp (func_get_arg($nContador), "WHERE") ) {
				$cSql .= " WHERE " ;
				$nContador++;
				$cSeparador = " AND ";
				$bPrimero = true; // Vuelve a poner el flag del primero para saltear la primera ,
			}


			$cValor = func_get_arg($nContador + 1);
			$cValor = $this->dbValue( func_get_arg($nContador + 1) );

			if ( $bPrimero )
				$bPrimero = false;
			else
				$cSql .= $cSeparador;

			$cSql .= func_get_arg($nContador) . " = " . $cValor;

		}

		$bExito = ( odbc_exec ( $this->idCon, $cSql) == FALSE ) ? false:  true;

		if ($bExito === false) {
			addMessage("Error en el query: $cSql");
		}

		return $bExito;
	}

	// Parametros $cTabla, { $cClave, $cValor }
	function delete( $cTabla, $cClave, $cValor ) {
		$nContador = 0;
		$cValor = "";
		$bPrimero = true;

		// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		$this->cSql = "DELETE FROM  " . $cTabla . " WHERE ";

		for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) {
			$cValor = func_get_arg($nContador + 1);
			if ( substr(func_get_arg($nContador - 1), 0, 1) == "c" ) {
				$cValor = "'" . $cValor . "'";
			}

			if ( $bPrimero )
				$bPrimero = false;
			else
				$this->cSql .= " AND ";

			$this->cSql .= func_get_arg($nContador) . " = " . $cValor;

		}

		$bExito = ( odbc_exec ( $this->idCon, $this->cSql) == FALSE ) ? false:  true;
		if($bExito === false) {
			addMessage($this->cSql);
		}
		
		return $bExito;

	}

	function query( $cSql ) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;

		if ( $this->idCon == 0 && !$this->connect() )
				return false;

		if ( $this->idQuery != 0 ) {
			odbc_free_result ( $this->idQuery );
		}

		$this->idQuery = odbc_exec ( $this->idCon, $cSql );

		if ( $this->idQuery == TRUE ) {
			$this->cantCampos = odbc_num_fields ( $this->idQuery );
		}		
		return $this->idQuery;
	}

	function moveNext() {
		if ( $this->idQuery == 0 )
			return 0;
		
		$nRet = odbc_fetch_into( $this->idQuery , $this->aFields ) ;

		if ( $nRet  == FALSE )
			return FALSE;

		// lo hace Asociativo
		for( $nIndex = 0 ; $nIndex < odbc_num_fields( $this->idQuery ); $nIndex ++ ) {					
			$this->aFields[odbc_field_name ($this->idQuery, $nIndex + 1)] =  $this->aFields[$nIndex];
		}

		return TRUE;
	}

	/// makeOptions( $cSql, $Valor , $bObligatorio = false)
	// Recibe un SQL de tipo "Select Codigo, Descripcion", y genera los options que van dentro del
	// TAG SELECT de un HTML.
	function makeOptions( $cSql, $Valor , $bObligatorio = false, $nLen = 0, $bFiltrarMigracion = true) {
		$this->cSql = $cSql = $this->changeSql ( $cSql ) ;
		
		$cRet = '';
		/// Filtra los registros de Migracion
		if(strpos($cSql, '*') === false && $bFiltrarMigracion == true){
			$cSql = trim(strtolower($cSql));
			$cCampo = trim(substr($cSql, 6, strpos($cSql, ',', 6) - 6));
			$nPosOrder = strpos($cSql,'order by ');
			if( $nPosOrder === false ){
				$cSql .= (strpos( $cSql, 'where')===false ? ' where ': ' and ') . $cCampo . ' > 0 ';
			} else {
				$cOrderBy = substr($cSql,$nPosOrder);
				$cSql = substr($cSql,0, $nPosOrder);
				$cSql .= (strpos( $cSql, 'where')===false ? ' where ': ' and ') . $cCampo . ' > 0 ';
				$cSql .= $cOrderBy;
			}
		}

		$this->query($cSql);

		if ( ! $bObligatorio ) {
			$cRet .= "<option ";
			if ($Valor == "0") $cRet .= " selected ";
			$cRet .= " value=''>-</option>";

		}

		while( $this->moveNext() == TRUE) {
			$cRet .= "<option ";
			if ($Valor == $this->aFields[0] ) {
				$cRet .= " selected ";				
			}
			$cRet .= "value='". $this->aFields[0] ."'>";
			if($nLen > 0)
				 $cRet .= strFit($this->aFields[1],$nLen);
			else
				$cRet .= $this->aFields[1];

			$cRet .= "</option>\r\n";
		}
		return $cRet;
	}

	// Devuelve el numero total de Registros del Query, independientemente de que se haya puesto un TOP
	function totalFilas( $cSql, $cPatron = "FROM") {	
		$cSql = strtoupper( $cSql);
		$cPatron = strtoupper($cPatron);
		$nPos = strpos($cSql, $cPatron );	
		$cSql = "SELECT COUNT(*) " . substr( $cSql , $nPos );
		$nqRows = $this->getData($cSql);
	
		return $nqRows;
	}
	
	function changeSql ( $cSql ) {
		$nPos = 0;
		$nLen = strlen($cSql) ;					
		
		// Busco la Posicion del FROM del SELECT
		$bFin = 0;
		$bEnParentesis = 0;		
		while ( $nPos < $nLen && $bFin == 0 ) {
			if ( $cSql[$nPos] == '(' ) $bEnParentesis++;
			if ( $cSql[$nPos] == ')' ) $bEnParentesis--;
			
			if ( $bEnParentesis == 0 && strtoupper(substr( $cSql, $nPos, 5)) == "FROM " ) {
				$nPosFrom = $nPos + 5;
				$bFin = 1;
			}
			
			$nPos++;
		}

		if ( $nPosFrom ) {
			
			while ( $nPos < $nLen ) {				
				if ( strtoupper(substr( $cSql, $nPos, 5)) == "JOIN " ) {
					$cSql = substr( $cSql, 0, $nPosFrom ) . " ( " . 
							substr( $cSql, $nPosFrom , $nPos - $nPosFrom - 1  ) . " ) INNER " .
							substr( $cSql, $nPos );
							
					$nPos += 17;
					$bEntro = 1;
				}
								
				if ( strtoupper(substr( $cSql, $nPos, 10)) == "LEFT JOIN " ) {
					$cSql = substr( $cSql, 0, $nPosFrom ) . " ( " . 
							substr( $cSql, $nPosFrom , $nPos - $nPosFrom - 1  ) . " ) " .
							substr( $cSql, $nPos );
							
					$nPos += 16;
				}
				
				$nPos++;
			}						
		}	
						
		return $cSql;		
	}

	function __goTo( $nRow = -1) {
		$nMaxRows = odbc_num_rows ( $this->idQuery );
		
		if ( $this->idQuery == 0 )
			return false;

		if ( $nRow < 1 ) {
			$nRow = 1;
		}

		if ( $nMaxRows > 0 && $nRow >= $nMaxRows ) {
			return false;
		}		

		if ( ! odbc_fetch_row ( $this->idQuery, $nRow ) ) {
			return false;
		}

		return true;
	}

	function count() {
		if ( $this->idQuery == 0 )
			return false;

		return odbc_num_rows ( $this->idQuery );
	}
	
}

?>
